﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using FinanSoft.Entities;
using FinanSoft.BusinessLayer;

namespace FinanSoft.SaleRouteReports
{
    class SaleRouteManager
    {
        #region Singleton

        private static SaleRouteManager _instance;

        private SaleRouteManager()
        {
        }         
        
        /// <summary>
        /// Método para implementar el patrón de Singleton
        /// </summary>
        /// <returns>Instancia única de la clase</returns>
        public static SaleRouteManager GetInstance()
        {
            if (_instance == null)
                _instance = new SaleRouteManager();
            return _instance;
        }

        #endregion

        #region Public Methods
        public SaleReport[] GetSaleReport(int auxId, int itemId)
        {
            Dictionary<string, SaleReport> reportHash = new Dictionary<string, SaleReport>();
            List<SaleReportRawData> rawData = SaleRouteDataManager.GetInstance().GetSaleData(auxId, itemId);
            int lastInvoice = 0;
            List<string> invoiceKeys = new List<string>();
            foreach (SaleReportRawData data in rawData)
            {
                // Obtengo el precio por unidad en moneda local
                double unitLocalAmount = MoneyManager.GetInstance().GetCurrency(data.CurrencyId).ToLocalCurrency * data.UnitPrice;
                // Verifico si hay que hacer el acumulado de una nueva factura
                if (lastInvoice != data.DocumentId)
                {
                    foreach (string invoiceKey in invoiceKeys)
                        reportHash[invoiceKey].InvoiceAmount++;
                    invoiceKeys = new List<string>();
                    lastInvoice = data.DocumentId;
                }
                string key = data.ItemId.ToString() + "-" + data.ClientId.ToString();
                // Agrego un nuevo reporte de un cliente para un artículo
                if (!reportHash.ContainsKey(key))
                {
                    reportHash.Add(key, new SaleReport(
                        data.ClientId, data.ItemId, data.SaleDate,
                        0, 0, 0, 0));
                }
                // Agrego información adicional a un reporte existente de un cliente para un artículo
                SaleReport report = reportHash[key];
                report.TotalQuantity += data.Quantity;
                report.TotalSold += data.Quantity * unitLocalAmount;
                if (report.LastSaleDate < data.SaleDate)
                    report.LastSaleDate = data.SaleDate;
                report.AddHistoryDetail(new SaleReportHistoryDetail(data.SaleDate, data.Quantity, unitLocalAmount));
                if(!invoiceKeys.Contains(key))
                    invoiceKeys.Add(key);
            }
            // Este ciclo adicional debe hacerse para tomar en cuenta la última factura
            foreach (string invoiceKey in invoiceKeys)
                reportHash[invoiceKey].InvoiceAmount++;
            // Obtengo el promedio de montos para cada artículo por cliente
            foreach (SaleReport updatedReport in reportHash.Values)
                updatedReport.InvoiceAverageSold = updatedReport.TotalSold / updatedReport.InvoiceAmount;
            return reportHash.Values.ToArray();
        }
        #endregion
    }
}
